<script setup lang="ts">
import {nextTick, onActivated, onMounted, reactive, ref, watch} from "vue";
import {executeRest, getSimpleIndices, getSimpleTemplates} from "@/views/api/elastic.ts"
import {error} from "@/utils/message.ts";
import {useRoute} from "vue-router"
import {useSiteStore} from "@/store/modules/site.ts"
import {History} from "@/views/types/history.ts";
import RestHistory from "@/views/components/RestHistory.vue";
import JsonText from "@/components/JsonText.vue";
import {IndexStatus} from "@/views/types";
import {createHelpers, Helper, HttpMethod, Parameter} from "@/views/api/rest.ts";

const route=useRoute();
const isRecord = ref(true);
const parameters = ref<Array<Parameter>>([{
  "key":"format",
  "value":"json"
},{
  "key":"h",
  "value":""
},{
  "key":"help",
  "value":""
},{
  "key":"conflicts",
  "value":"proceed"
},{
  "key":"wait_for_completion",
  "value":"false"
},{
  "key":"refresh",
  "value":"true"
},{
  "key":"detailed",
  "value":"true"
},{
  "key":"actions",
  "value":"true"
}]);
const drawer = ref(false);
const loading = ref(false);
const result = ref<any>(null);
const helpers = ref<Array<Helper>>([]);
const histories = reactive<Array<History>>([]);
const indices =ref<Array<string>>([]);
const templates =ref<Array<string>>([]);
const form = reactive({
  url: "/index/_search",
  method: HttpMethod.post,
  parameters:[],
  body: "",
})
watch(form, () => {
  isRecord.value = true;
}, {deep: true});

const formatBody = () => {
  try {
    let body = JSON.stringify(JSON.parse(form.body), null, 2)
    form.body = body;
  } catch (e) {
    console.log(e)
    error(e);
  }
}
const execute = () => {
  result.value=null;
  loading.value = true;
  executeRest(form.method, form.url,form.parameters, form.body).then(res => {
    result.value=res;
    insertHistory();
  }).catch((err) => {
    error(err.message);
    if (err?.response?.data) {
      result.value=err?.response?.data
    }
  }).finally(() => {
    loading.value = false;
  })
}
const insertHistory = () => {
  if (isRecord.value) {
    window.api.history.insert(({
      siteId: useSiteStore()._id,
      method: form.method,
      url: form.url,
      body: form.body,
      time: new Date().getTime()
    })).then(res => {
      isRecord.value = false;
      histories.splice(0, 0, res);
    })
  }
}
const onSelectHistory = (row: History) => {
  form.method = <HttpMethod>row.method;
  form.body = row.body;
  form.url = row.url;
  nextTick(() => {
    isRecord.value = false;
    drawer.value = false;
  })
}
const onDeleteHistory = (id) => {
  let index = histories.findIndex(data => data._id === id);
  if (index > -1) {
    histories.splice(index, 1);
  }
}
onMounted(() => {
  window.api.history.getList(useSiteStore()._id).then(res => {
    if (res && res.length > 0) {
      histories.push(...res);
    }
  })
  getSimpleIndices().then(data => {
    if(data && data.length > 0) {
      indices.value=data.filter(d=>d.status===IndexStatus.open).map(data=>data.index);
      createUriHelpers();
    }
  })
  getSimpleTemplates().then(data => {
    if(data && data.length > 0) {
      templates.value=data.map(data=>data.name);
      createUriHelpers();
    }
  })
})
const createUriHelpers = () =>{
  helpers.value=createHelpers(indices.value,templates.value);
}
onActivated(()=>{
  let query = route.query;
  if(query && query.url){
    form.url=<string>query.url;
    result.value=null;
  }
  if(query && query.body){
    form.body=<string>query.body;
  }
  if(query && query.method){
    form.method=<HttpMethod>query.method;
  }
})
const queryHelperSearch =(query:string,callback:any) =>{
  const results = query
      ? helpers.value.filter(createFilter(query))
      : helpers.value
  callback(results)
}

const createFilter = (queryString: string) => {
  return (help: Helper) => {
    return (
        help.value.toLowerCase().indexOf(queryString.toLowerCase()) >-1
    )
  }
}
const handleSelect = (helper:Helper) =>{
  if(helper){
    form.method=helper.method;
    form.parameters=helper.parameters||[];
    debugger
    form.body=helper.body!=null?JSON.stringify(helper.body,null,4):"";
  }
}
const addParameter = () =>{
  form.parameters.push({
    key:"",
    value:""
  })
}
const deleteParameter = (index:number) =>{
  form.parameters.splice(index,1);
}
const onParameterChange = (key:string,index:number) =>{
  const parameter=parameters.value.find(d=>d.key===key)
  form.parameters[index].value="";
  if(parameter){
    form.parameters[index].value=parameter.value;
  }
}
</script>

<template>
  <div class="container">
    <el-drawer v-model="drawer" size="35%" title="历史记录">
      <RestHistory v-model:list="histories" @success="onSelectHistory" @on-delete="onDeleteHistory" @cancel="drawer=false"></RestHistory>
    </el-drawer>
    <el-row :gutter="10">
      <el-col :span="6" style="height: calc(100vh - 130px);overflow: auto">
        <el-form ref="formRef" :model="form" label-width="5px">
          <el-row>
            <el-col :span="24">
              <el-form-item prop="url">
                <el-autocomplete size="medium" clearable v-model="form.url" placeholder="/index/_search" @select="handleSelect" :fetch-suggestions="queryHelperSearch">
                  <template #prepend>
                    <el-select size="medium" v-model="form.method" style="width: 100px">
                      <el-option value="post" label="POST"></el-option>
                      <el-option value="get" label="GET"></el-option>
                      <el-option value="put" label="PUT"></el-option>
                      <el-option value="delete" label="DELETE"></el-option>
                    </el-select>
                  </template>
                </el-autocomplete>
              </el-form-item>
            </el-col>
          </el-row>
            <el-form-item prop="parameters">
              <div style="width:100%">
                <el-button @click="addParameter">添加参数</el-button>
              </div>
              <el-table :data="form.parameters">
                <el-table-column label="键" align="center">
                  <template #default="scope">
                    <el-form-item
                        :prop="'parameters[' + scope.$index + '].key'"
                        :rules="{
                      required: true,
                      message: '键不能为空',
                      trigger: ['blur', 'change']
                    }"
                    >
                     <el-select filterable v-model="scope.row.key" clearable style="width: 100%" allow-create @change="(k)=>onParameterChange(k,scope.$index)">
                       <el-option v-for="item  in parameters" :value="item.key" :label="item.key">
                       </el-option>
                     </el-select>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column label="值" align="center">
                  <template #default="scope">
                    <el-form-item
                        :prop="'parameters[' + scope.$index + '].value'"
                        :rules="{
                      required: false,
                      message: '值不能为空',
                      trigger: ['blur', 'change']
                    }"
                    >
                      <el-input v-model="scope.row.value"/>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column label="操作" align="center" width="100px">
                  <template #default="scope">
                    <el-button
                        type="danger"
                        @click="deleteParameter(scope.$index)"
                    >删除</el-button
                    >
                  </template>
                </el-table-column>
              </el-table>
            </el-form-item>
          <el-row>
            <el-col :span="24">
              <el-form-item prop="body">
                <el-input v-model="form.body" type="textarea" :rows="20" spellcheck="false"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div style="display: flex;justify-content: space-between">
          <div>
            <el-button text @click="drawer=true">历史记录</el-button>
          </div>
          <div>
            <el-button type="primary" :disabled="!form.body"  @click="formatBody">格式化</el-button>
            <el-button type="primary" :disabled="!form.url" :loading="loading" @click="execute">执行</el-button>
          </div>
        </div>
      </el-col>
      <el-col :span="18">
        <div v-loading="loading" style="height: calc(100vh - 130px);padding: 2px;border: solid 1px var(--el-border-color)">
          <JsonText :value="result"></JsonText>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<style scoped>

</style>